/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_zml.htm
 *
 * Zhiqim Zml is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.zml.statement;

import java.lang.reflect.InvocationTargetException;

import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.zml.Expression;
import org.zhiqim.zml.ExpressionParser;
import org.zhiqim.zml.Statement;
import org.zhiqim.zml.ZmlEngine;
import org.zhiqim.zml.ZmlVariable;
import org.zhiqim.zml.exception.ExpressionException;
import org.zhiqim.zml.exception.StatementException;

/**
 * 包含语句，格式为：<#include "/zview/include.zml"/><br>
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class _Include extends Statement
{
    private Expression expression;
    
    @Override
    public boolean isNesting()
    {
        return true;
    }
    
    @Override
    public void parseStatement() throws StatementException
    {
        String s = Strings.trim(getStatement(), INCLUDE_BEGIN, INCLUDE_END);
        if (Validates.isEmptyBlank(s))
            throw new StatementException(this, INCLUDE + "未配置被包含的文件路径");
        
        try
        {
            expression = ExpressionParser.parseExpression(s);
        }
        catch (ExpressionException e)
        {
            throw new StatementException(this, INCLUDE + e.getMessage());
        }
    }

    @Override
    public String process(ZmlVariable variableMap) throws StatementException
    {//执行包含的ZML
        try
        {
            String path = getIncludePath(variableMap);
            ZmlEngine engine = getZml().getEngine();
            
            return engine.getZml(path).process(variableMap, getZml());
        }
        catch (StatementException e) 
        {
            throw e;
        }
        catch (Exception e)
        {
            if (e instanceof InvocationTargetException)
                throw new StatementException(this, INCLUDE + ((InvocationTargetException)e).getTargetException().getMessage());
            else if (e.getCause() != null)
                throw new StatementException(this, INCLUDE + e.getCause().getMessage());
            else
                throw new StatementException(this, INCLUDE + e.getMessage());
        }
    }
    
    /** 包含的ZML优先变量定义 */
    public void define(ZmlVariable variableMap) throws StatementException
    {
        try
        {
            String path = getIncludePath(variableMap);
            ZmlEngine engine = getZml().getEngine();
            
            engine.getZml(path).define(variableMap);
        }
        catch (StatementException e) 
        {
            throw e;
        }
        catch (Exception e)
        {
            if (e instanceof InvocationTargetException)
                throw new StatementException(this, INCLUDE + ((InvocationTargetException)e).getTargetException().getMessage());
            else
                throw new StatementException(this, INCLUDE + e.getMessage());
        }
    }
    
    /** 获取包含的ZML路径 */
    public String getIncludePath(ZmlVariable variableMap) throws StatementException
    {
        try
        {
            return String.valueOf(expression.build(variableMap));
        }
        catch (ExpressionException e)
        {
            throw new StatementException(this, INCLUDE + e.getMessage());
        }
    }
}
